<?php

namespace app\common\controller;

use AlibabaCloud\SDK\Vod\V20170321\Models\AddEditingProjectRequest;
use AlibabaCloud\SDK\Vod\V20170321\Models\CreateUploadVideoRequest;
use AlibabaCloud\SDK\Vod\V20170321\Models\DeleteMezzaninesRequest;
use AlibabaCloud\SDK\Vod\V20170321\Models\DeleteMezzaninesResponse;
use AlibabaCloud\SDK\Vod\V20170321\Models\GetPlayInfoRequest;
use AlibabaCloud\SDK\Vod\V20170321\Models\GetPlayInfoResponse;
use AlibabaCloud\SDK\Vod\V20170321\Models\ProduceEditingProjectVideoRequest;
use AlibabaCloud\SDK\Vod\V20170321\Vod;
use Darabonba\OpenApi\Models\Config;
use OSS\OssClient;
use think\Cache;

class AliVod
{
    private function createClient($accessKeyId = '', $accessKeySecret = ''): Vod
    {
        if (empty($accessKeyId) || empty($accessKeySecret)) {
            $config = Cache::get('cdk');
            if (empty($config)) {
                $data_auth = json_decode(file_get_contents('http://zk.ydk1.cn/index.php/api/token/auth'), true);
                if (!isset($data_auth['code'])) throw new \Exception('获取授权信息失败');
                if ($data_auth['code'] === 0) throw new \Exception($data_auth['msg']);

                $config = $data_auth['data'];
                Cache::set('cdk', $config, 86400);
            }

            $accessKeyId = $config['accessKeyId'];
            $accessKeySecret = $config['accessKeySecret'];
        }
        if (empty($accessKeyId) || empty($accessKeySecret)) throw new \Exception('授权信息错误');

        $config = new Config([
            'accessKeyId' => $accessKeyId,
            'accessKeySecret' => $accessKeySecret,
        ]);
        $config->endpoint = 'vod.cn-shenzhen.aliyuncs.com';
        return new Vod($config);
    }

    public function uploadVideo($info)
    {
        try {
            $videoId = $this->createClient()->createUploadVideo(new CreateUploadVideoRequest([
                'fileName' => $info['fileName'],
                'title' => $info['title'],
            ]));
            $uploadAuth = json_decode(base64_decode($videoId->body->uploadAuth), true);
            $uploadAddress = json_decode(base64_decode($videoId->body->uploadAddress), true);

            $ossClient = new OssClient($uploadAuth['AccessKeyId'], $uploadAuth['AccessKeySecret'], $uploadAddress['Endpoint'], false, $uploadAuth['SecurityToken']);
            $ossClient->setTimeout(86400 * 7); //设置请求超时时间，单位秒，默认是5184000秒
            $ossClient->setConnectTimeout(10); //设置连接超时时间，单位秒，默认是10秒
            $ossUploadResultData = $ossClient->uploadFile($uploadAddress['Bucket'], $uploadAddress['FileName'], $info['fileName']);

            return json_decode(json_encode(['FileId' => $videoId->body->videoId, 'MediaUrl' => $ossUploadResultData['oss-request-url'] ?? '']));
        } catch (\Exception $e) {
            return $e->getMessage();
        }
    }

    public function compose($videoData, $voiceData, $music, $name): array
    {
        $data = [];
        try {
            $outputVideoData = [];
            foreach ($videoData as $v) {
                $outputVideoData['VideoTrackClips'][] = [
                    'MediaId' => $v,
                    'Effects' => [
                        [
                            'Type' => 'Volume',
                            'Gain' => '0'
                        ]
                    ]
                ];
            }
            $data['VideoTracks'][] = $outputVideoData;

            $audioData = array_merge($voiceData, [$music]);
            $outputAudioData = [];
            foreach ($audioData as $v) {
                $outputAudioData['AudioTrackClips'][] = [
                    'MediaId' => $v,
                    'TimelineIn' => 0
                ];
            }
            $data['AudioTracks'][] = $outputAudioData;

            $client = $this->createClient();
            $res = $client->produceEditingProjectVideo(new ProduceEditingProjectVideoRequest([
                'projectId' => $client->addEditingProject(new AddEditingProjectRequest(['title' => $name,]))->body->project->projectId,
                'timeline' => json_encode($data),
            ]));
            if (empty($res->body->mediaId)) {
                return ['status' => 'error', 'task_id' => '', 'exception' => json_encode($res)];
            } else {
                return ['status' => 'ongoing', 'task_id' => $res->body->mediaId, 'exception' => ''];
            }
        } catch (\Exception $e) {
            return ['status' => 'error', 'task_id' => '', 'exception' => $e->getMessage()];
        }
    }

    public function getPlayInfo($mediaId): GetPlayInfoResponse
    {
        return $this->createClient()->getPlayInfo(new GetPlayInfoRequest(['videoId' => $mediaId]));
    }

    public function deleteMezzanines($videoIdData): DeleteMezzaninesResponse
    {
        return $this->createClient()->deleteMezzanines(new DeleteMezzaninesRequest(['VideoIds' => implode(',', $videoIdData)]));
    }

    public static function curl($url, $data = [], $isReturnResponseHeader = 0, $requestHeaderData = [], $opts = [], $errorExit = 1, $isFile = 0)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 9);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        if ($data) {
            curl_setopt($ch, CURLOPT_POST, TRUE);
            if ($isFile) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            } else {
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
                $requestHeaderData = array_merge($requestHeaderData, ['Content-Type: application/json;charset="UTF-8"']);
            }
        }

        if ($requestHeaderData) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaderData);
        }

        if ($opts) {
            foreach ($opts as $opt => $val) {
                curl_setopt($ch, $opt, $val);
            }
        }

        $response = curl_exec($ch);
        $curlError = curl_error($ch);
        $header = curl_getinfo($ch);
        curl_close($ch);

        if ($response === FALSE && $errorExit) {
            exit('CURL Error:' . $curlError);
        } else if ($isReturnResponseHeader) {
            $data = array();
            $data['header'] = $header;
            $data['response'] = $response;
            return $data;
        } else {
            return $response;
        }
    }

}
